package cn.south.campus.business.service.impl;

import cn.south.campus.business.config.TokenConfig;
import cn.south.campus.business.mapper.UserMapper;
import cn.south.campus.business.model.bo.LoginContext;
import cn.south.campus.business.model.bo.LoginInfo;
import cn.south.campus.business.model.entity.Student;
import cn.south.campus.business.model.entity.User;
import cn.south.campus.business.model.enums.StudentEnums;
import cn.south.campus.business.model.req.LoginReq;
import cn.south.campus.business.model.vo.MyPageVo;
import cn.south.campus.business.model.vo.UserVo;
import cn.south.campus.business.model.vo.WalletVo;
import cn.south.campus.business.service.StudentService;
import cn.south.campus.business.service.UserService;
import cn.south.campus.business.service.WalletService;
import cn.south.campus.common.cache.CacheService;
import cn.south.campus.common.model.enums.CommonEnums;
import cn.south.campus.common.utils.AssertUtils;
import cn.south.campus.common.utils.MD5Utils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author chow
 * @since 2024-11-13
 */
@AllArgsConstructor
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private final UserMapper userMapper;

    private final StudentService studentService;

    private final WalletService walletService;

    private final CacheService cacheService;

    @Override
    public UserVo selectByPhoneAndPwd(String phone, String password) {
        String encryptPwd = MD5Utils.MD5(TokenConfig.SECRET + password);
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getPhone, phone).eq(User::getPassword, encryptPwd);
        return UserVo.convert(userMapper.selectOne(wrapper));
    }

    @Override
    public UserVo detail(Long id) {
        return UserVo.convert(userMapper.selectById(id));
    }

    @Override
    public void insert(LoginReq req) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getPhone, req.getPhone());
        AssertUtils.isNull(userMapper.selectOne(wrapper), CommonEnums.DATA_REPEAT_ERROR);
        User user = new User();
        user.setPhone(req.getPhone());
        user.setNickname("学生" + req.getPhone().substring(8));
        user.setPassword(MD5Utils.MD5(TokenConfig.SECRET + req.getPassword()));
        userMapper.insert(user);
    }

    @Override
    public void modify(UserVo vo) {
        LoginInfo context = LoginContext.getContext();
        User user = userMapper.selectById(context.getId());
        AssertUtils.isNotNull(user, CommonEnums.DATA_HAS_NOT_ERROR);
        LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<User>()
                .set(StringUtils.hasText(vo.getPhone()), User::getPhone, vo.getPhone())
                .set(StringUtils.hasText(vo.getNickname()), User::getNickname, vo.getNickname())
                .set(StringUtils.hasText(vo.getAvatar()), User::getAvatar, vo.getAvatar())
                .set(vo.getGender() != null, User::getGender, vo.getGender())
                .eq(User::getId, context.getId());
        userMapper.update(user, wrapper);
        context.setPhone(StringUtils.hasText(vo.getPhone()) ? vo.getPhone() : user.getPhone());
        context.setNickname(StringUtils.hasText(vo.getNickname()) ? vo.getNickname() : user.getNickname());
        context.setAvatar(StringUtils.hasText(vo.getAvatar()) ? vo.getAvatar() : user.getAvatar());
        context.setGender(vo.getGender() != null ? vo.getGender() : user.getGender());
        LoginContext.setContext(context);
        cacheService.setCacheObject(context.getToken(), context, TokenConfig.EXPIRE);
    }

    @Override
    public MyPageVo info() {
        LoginInfo context = LoginContext.getContext();
        String avatar = context.getAvatar();
        String nickname = context.getNickname();
        MyPageVo myPageVo = new MyPageVo();
        myPageVo.setAvatar(avatar);
        myPageVo.setNickname(nickname);
        WalletVo walletVo = walletService.queryBalance();
        myPageVo.setBalance(walletVo.getBalance().toString());
        myPageVo.setFrozenAmount(walletVo.getFrozenAmount().toString());
        Student student = studentService.getOne(new LambdaQueryWrapper<Student>().eq(Student::getUserId, context.getId()));
        myPageVo.setAuthStatus(student == null ? StudentEnums.AuthStatusEnums.NO_AUTH.getCode() : student.getStatus());
        return myPageVo;
    }
}
